/**
 * Copyright [2012-2013] [Guðmundur Björn Birkisson]
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. Copyright [2012-2013] [Guðmundur Björn Birkisson]
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ---------------------------------------------------------------------------
 * 
 * Class name:  TextEditor
 * 
 * Description of class:
 * 
 * UI that allows editing of text and syntax highlighting.
 * 
 */

package karel.editors.texteditor;

import java.awt.Color;
import java.awt.Font;
import java.io.Reader;
import java.io.StringReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Element;
import jsyntaxpane.DefaultSyntaxKit;
import karel.lang.RDParserException;
import karel.util.FontLoader;

/**
 *
 * @author Gummi
 */
public class TextEditor extends javax.swing.JPanel {

    private boolean isHighlighted;
    
    /**
     * Creates new form TEditor
     */
    public TextEditor() {
        DefaultSyntaxKit.initKit();
        DefaultSyntaxKit.registerContentType("text/karel", "karel.lang.syntaxhighlight.KarelSyntaxHighlightingKit");
        initComponents();

        resetTextEditor();
    }

    /**
     * This resets the editor and clears all undo/redo commands.
     */
    private void resetTextEditor() {
        textPanel.setContentType("text/karel");
        textPanel.setFont(FontLoader.getDefaultFont(Font.PLAIN, FontLoader.TextEditorFontSize));

        TextEditorLineNumber tln = new TextEditorLineNumber(textPanel);
        tln.setCurrentLineForeground(new Color(223, 89, 0));
        scrollPanel.setRowHeaderView(tln);
        isHighlighted = false;
    }

    /**
     * Removes all highlights from editor
     */
    public void removeHighlights() {
        if (isHighlighted) {
            textPanel.getHighlighter().removeAllHighlights();
            isHighlighted = false;
        }
    }

    /**
     * Highlights error in text editor in position line e.line and column
     * e.column with the length e.length.
     *
     * @param e
     */
    public void highlightError(RDParserException e) {
        removeHighlights();
        isHighlighted = true;
        String[] lines = textPanel.getText().split("\n");
        int p0 = e.colomn;
        int i;
        for (i = 0; i < e.line; i++) {
            p0 += lines[i].length() + 1;
        }
        
        int p1 = p0 + e.length;
        if(e.length == 0) {
            p1++;
        }
        try {
            textPanel.setCaretPosition(p0);
            textPanel.getHighlighter().addHighlight(p0, p1,
                    new DefaultHighlighter.DefaultHighlightPainter(new Color(1.0f, 0.3f, 0.0f)));
            textPanel.setCaretPosition(p1);
            textPanel.grabFocus();
        } catch (BadLocationException ex) {
            Logger.getLogger(TextEditor.class.getName()).log(Level.FINE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(TextEditor.class.getName()).log(Level.FINE, null, ex);
        }
    }

    /**
     * Highlights a whole line in the text editor.
     * @param line 
     */
    public void highlightLine(int line) {
        removeHighlights();
        isHighlighted = true;
        Element map = textPanel.getDocument().getDefaultRootElement();
        Element lineElem = null;
        try {
            if (line < 0) {
                throw new BadLocationException("Negative line", -1);
            } else if (line >= map.getElementCount()) {
                throw new BadLocationException("No such line", textPanel.getDocument().getLength() + 1);
            } else {
                lineElem = map.getElement(line);
            }
            textPanel.setCaretPosition(lineElem.getStartOffset());
            textPanel.getHighlighter().addHighlight(lineElem.getStartOffset(), lineElem.getEndOffset(), new DefaultHighlighter.DefaultHighlightPainter(Color.lightGray));
        } catch (BadLocationException ex) {
        }
    }

    /**
     * Sets the text in the text editor and resets the editor.
     * @param txt 
     */
    public void setText(String txt) {
        textPanel.setContentType("EMPTY");
        textPanel.setText("");
        resetTextEditor();
        textPanel.setText(txt);
    }
    
    /**
     * Returns a String of current text in editor.
     * @return 
     */
    public String getText() {
        return textPanel.getText();
    }
    
    /**
     * Returns a String reader of current text in editor.
     * @return 
     */
    public Reader getReader() {
        return new StringReader(textPanel.getText());
    }
    
    /**
     * Sets whether the texteditor is editable or not.
     * @param canEdit 
     */
    public void setEditable(boolean canEdit) {
        textPanel.setEditable(canEdit);
    }
    
    /*
     * Here below is auto generated code from NetBeans IDE 7.2.1
     */
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        scrollPanel = new javax.swing.JScrollPane();
        textPanel = new javax.swing.JEditorPane();

        setLayout(new java.awt.BorderLayout());

        textPanel.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                textPanelKeyTyped(evt);
            }
        });
        scrollPanel.setViewportView(textPanel);

        add(scrollPanel, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void textPanelKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_textPanelKeyTyped
        if(textPanel.isEditable()) {
            removeHighlights();
        }
    }//GEN-LAST:event_textPanelKeyTyped

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane scrollPanel;
    private javax.swing.JEditorPane textPanel;
    // End of variables declaration//GEN-END:variables
}
